<?php
/**
 * Created by zxzTool.
 * User: zxz
 * Datetime: 2019/2/18 下午9:01
 */

namespace XinYaTable\Forms\Utils;


use XinYaTable\Forms\Models\EloquentForm;
use XinYaTable\Forms\Models\EloquentFormCustomView;
use XinYaTable\Forms\Models\EloquentFormField;
use XinYaTable\Forms\Models\EloquentFormFieldOption;
use XinYaTable\Forms\Models\EloquentFormFilterGroup;
use XinYaTable\Forms\Models\EloquentFormFilterGroupField;
use Illuminate\Database\DatabaseManager;

abstract class BaseFormFieldMaker {
    const FORM_TITLE      = '';
    const FORM_TABLE_NAME = '';
    
    /**
     *
     */
    const FIELD_KEY = '--fields--';
    /**
     *
     */
    const OPTION_KEY = '--option--';
    
    /**
     *
     */
    const FILTER_GROUP_KEY = '--filterGroup--';
    
    /**
     * @var int
     */
    protected $formId = 0;
    
    /**
     * @var float|int
     */
    protected $_mTime;
    /**
     * @var EloquentForm
     */
    protected $_eloquentForm;
    
    /**
     * @var EloquentFormField
     */
    protected $_eloquentFormField;
    
    /**
     * @var EloquentFormFieldOption
     */
    protected $_eloquentFormFieldOption;
    
    /**
     * @var EloquentFormCustomView
     */
    protected $_eloquentFormCustomView;
    
    /**
     * @var EloquentFormFilterGroup
     */
    protected $_eloquentFormFilterGroup;
    
    /**
     * @var DatabaseManager
     */
    protected $_databaseManager;
    
    /**
     * BaseFormFieldMaker constructor.
     */
    function __construct() {
        $this->_mTime = mTime();
        $this->setEloquentForm();
        $this->setEloquentFormField();
        $this->setEloquentFormFieldOption();
        $this->setDatabaseManager();
        $this->setEloquentFormCustomView();
        $this->_eloquentFormFilterGroup = app(EloquentFormFilterGroup::class);
    }
    
    /**
     * @return array
     */
    abstract protected function _getFormData();
    
    /**
     * @return void
     */
    public function setEloquentForm() {
        $this->_eloquentForm = app(EloquentForm::class);
    }
    
    
    /**
     * @return void
     */
    public function setEloquentFormField() {
        $this->_eloquentFormField = app(EloquentFormField::class);
    }
    
    
    /**
     * @return void
     */
    public function setEloquentFormFieldOption() {
        $this->_eloquentFormFieldOption = app(EloquentFormFieldOption::class);
    }
    
    
    /**
     * @return void
     */
    public function setDatabaseManager() {
        $this->_databaseManager = app(DatabaseManager::class);
    }
    
    
    /**
     * @return void
     */
    public function setEloquentFormCustomView() {
        $this->_eloquentFormCustomView = app(EloquentFormCustomView::class);
    }
    
    
    /**
     * @throws \ReflectionException
     */
    public function fill() {
        $formMarkerName = (new \ReflectionClass($this))->getShortName();
        echo ' 开始填充表单：' . $formMarkerName . PHP_EOL;
        echo ' --表单标题：' . static::FORM_TITLE . PHP_EOL;
        echo ' --表单表名：' . static::FORM_TABLE_NAME . PHP_EOL;
        $this->_doFill();
        echo ' 完成填充表单：' . $formMarkerName . PHP_EOL . PHP_EOL;
    }
    
    /**
     * 开始填充
     */
    public static function doFill() {
        (new static())->fill();
    }
    
    /**
     * 操作填充
     */
    protected function _doFill() {
        $this->_databaseManager->beginTransaction();
        try {
            $formDataInfo = $this->_getFormData();//插入表单条目并获取id
    
            //删除旧数据
            $oldFormId  = null;
            if ($formEl = $this->_eloquentForm->newQuery()->where('table_name', static::FORM_TABLE_NAME)->first()) {
                $formEl->delete();
                $oldFormId = $formEl->id;
    
                //删除对应options
                $fieldIdList = $this->_eloquentFormField->newQuery()->where('form_id', $formEl->id)->pluck('id');
                $fieldIdList && $this->_eloquentFormFieldOption->whereIn('field_id', $fieldIdList)->delete();
    
                $this->_eloquentFormField->newQuery()->where('form_id', $formEl->id)->delete();
                $this->_eloquentFormCustomView->newQuery()->where('form_id', $formEl->id)->delete();
            }
            
            $formInsertData = $formDataInfo;
            unset($formInsertData[self::FIELD_KEY]);
            unset($formInsertData[self::FILTER_GROUP_KEY]);
            $formInsertData['table_name'] = static::FORM_TABLE_NAME;
            $formInsertData['title'] = static::FORM_TITLE;
            $this->_attachTime($formInsertData);
            $newForm = $this->_eloquentForm->newInstance()
                ->fillable(array_keys($formInsertData))
                ->fill($formInsertData);
            $newForm->save();
            
            echo ' --表单插入ID：' . $newForm->id . PHP_EOL;
    
            if (isset($formDataInfo[self::FIELD_KEY])) {
                foreach ($formDataInfo[self::FIELD_KEY] as $key => $fieldInfo) {
                    $fieldInfo['form_id'] = $newForm->id;
                    is_string($fieldInfo['props']) && $fieldInfo['props'] = json_decode($fieldInfo['props'], true);
                    is_string($fieldInfo['validate']) && $fieldInfo['validate'] = json_decode($fieldInfo['validate'], true);
                    //插入新字段
                    $fieldInsertData = $fieldInfo;
                    unset($fieldInsertData[self::OPTION_KEY]);
                    $this->_attachTime($fieldInsertData);
                    $newField = $this->_eloquentFormField
                        ->newInstance()
                        ->fillable(array_keys($fieldInsertData))
                        ->fill($fieldInsertData);
                    $newField->save();
                    
                    //对应选项插入
                    if (isset($fieldInfo[self::OPTION_KEY])) {
                        foreach ($fieldInfo[self::OPTION_KEY] as $optionInfo) {
                            $optionInfo['field_id'] = $newField->id;
                            $this->_eloquentFormFieldOption->newInstance()->fillable(array_keys($optionInfo))
                                ->fill($optionInfo)
                                ->save();
                        }
                    }
                    //自定义显示插入
                    if ($newField->show_column) {
                        $newCustomView = $this->_eloquentFormCustomView->newInstance()
                            ->fill(
                                [
                                    'field_id'   => $newField->id,
                                    'title'      => $newField->title,
                                    'field_name' => $newField->field_name,
                                    'field_type' => $newField->field_type,
                                    'form_id'    => $newForm->id,
                                    'uid'        => -1,
                                    'order'      => $newField->order,
                                    'is_system'  => 1,
                                    'resizable'  => $newField->props['resizable'] ?? 1,
                                    'editable'   => $newField->props['editable'] ?? 0,
                                    'sortable'   => $newField->props['sortable'] ?? 0,
                                    'width'      => $newField->props['width'] ?? 0,
                                ]
                            );
                        $newCustomView->save();
                    }
                }
            }
            
            //填充过滤选项
            if (isset($formDataInfo[self::FILTER_GROUP_KEY])) {
                $this->_fillFilterGroup($newForm->id, $oldFormId, $formDataInfo[self::FILTER_GROUP_KEY]);
            }
            
        } catch (\Exception $e) {
            $this->_databaseManager->rollBack();
            echo ' 填充错误：' . $e->getMessage() . PHP_EOL;
            throw $e;
        }
        $this->_databaseManager->commit();
    }
    
    /**
     * 填充过滤选项
     *
     * @param int   $newFormId
     * @param int   $oldFormId
     * @param array $filterGroup
     */
    private function _fillFilterGroup(int $newFormId, $oldFormId, array $filterGroup) {
        
        if (!empty($filterGroup)) {
            echo ' --开始填充自定义筛选' . PHP_EOL;
    
            //删除过滤条件选项条目
            if ($oldFormId) {
                $filterGroupIds = $this->_eloquentFormFilterGroup->newQuery()->where('form_id', $oldFormId)->pluck('id')->toArray();
                $filterGroupIds && EloquentFormFilterGroupField::whereIn('filter_group_id', $filterGroupIds)->delete();
        
                $this->_eloquentFormFilterGroup->newQuery()->where('form_id', $oldFormId)->delete();
            }
            
            foreach ($filterGroup as $key => $filterInfo) {
                $filterInfo['form_id'] = $newFormId;
                $this->_attachTime($filterInfo);
                $_newFilter = $this->_eloquentFormFilterGroup
                    ->newInstance()
                    ->fill($filterInfo);
                $_newFilter->save();
                $_newFilter->conditions()->createMany($filterInfo['conditions'] ?? []);
            }
            echo ' --结束填充自定义筛选' . PHP_EOL;
        }
    }
    
    /**
     * @param $data
     */
    private function _attachTime(&$data) {
        !isset($data['created_at']) && ($data['created_at'] = $this->_mTime);
        !isset($data['updated_at']) && ($data['updated_at'] = $this->_mTime);
    }
}